package com.ybt.router.core.manager;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.log4j.Logger;
import org.dom4j.Document;
import org.dom4j.Element;
import org.dom4j.io.SAXReader;

import com.ybt.configration.IYBTConfigration;
import com.ybt.configration.YBTConfigration;
import com.ybt.router.core.message.factory.IMessageFactory;
import com.ybt.router.core.receiver.factory.IReceiverFactory;
import com.ybt.router.core.sender.factory.ISenderFactory;
import com.ybt.router.core.sender.manager.ISenderManager;

public class RouterTypeManager {
    private static volatile RouterTypeManager factory;
    private static String CONFIG_DIR = "router"+File.separator+"routerTypes.xml";
    private static Logger logger = Logger.getLogger(RouterTypeManager.class);
    private Map<String, RouterType> connectorMap;
    private String type;
    private RouterTypeManager() {
        CONFIG_DIR = YBTConfigration.getInstance().getProperty(
                IYBTConfigration.WORKFLOW_DEPLOY_PATH) + File.separator + CONFIG_DIR;
        type = YBTConfigration.getInstance().getProperty(
                IYBTConfigration.ROUTER_MESSAGE_TYPE);
        connectorMap = new HashMap<String, RouterType>();
        loadFromLocal();
    }

    public static RouterTypeManager getInstance() {
        if (factory == null) {
            synchronized(RouterTypeManager.class){
                if (factory == null) {
                    factory = new RouterTypeManager();
                }
            }
        }
        return factory;
    }

    /**
     * 根据协议类型获取协议解析器
     * @param type
     *            协议类型
     * @return 协议解析器
     * @throws ConnectorException
     */
    public IMessageFactory getMessageFactory(){
        RouterType p = connectorMap.get(type);
        if(p==null){
            throw new RuntimeException("unsupport router type :" + type);
        }
        return p.msgFactory;
    }


    public IReceiverFactory getReceverPoolFactory(){
        RouterType p = connectorMap.get(type);
        if(p==null){
            throw new RuntimeException("unsupport router type :" + type);
        }
        return p.receFactory;
    }

    public ISenderManager getSenderManager(){
        RouterType p = connectorMap.get(type);
        if(p==null){
            throw new RuntimeException("unsupport router type :" + type);
        }
        return p.sendFactory;
        
    }

    private void loadFromLocal() {
        File dir = new File(CONFIG_DIR);
        Document doc = null;
        if (dir.exists()) {
            // 配置文件已经存在
            FileInputStream fi = null;
            try {
                fi = new FileInputStream(dir);
                SAXReader saxReader = new SAXReader();
                doc = saxReader.read(new InputStreamReader(fi, "utf8"));
            } catch (Exception e) {
                logger.error("loading " + CONFIG_DIR + " error ", e);
                return;
            } finally {
                if (fi != null) {
                    try {
                        fi.close();
                    } catch (Exception e) {
                        logger.error("closeing " + CONFIG_DIR + " error ",
                                e);
                    }
                }
            }
        } else {
            // 配置文件没存在
            logger.error("the router type define file " + CONFIG_DIR + " don't exist ");
            return;
        }
        
        List<Element> eles = doc.getRootElement().elements("type");
        if (eles == null)
            return;

        // 加载链接器
        for (Element conEle : eles) {
            String type = conEle.attributeValue("type");
            String msg = conEle.elementTextTrim("msgFactory");
            String sender = conEle.elementTextTrim("senderManager");
            String receiver = conEle.elementTextTrim("receiverFactory");

            RouterType m = new RouterType();
            m.type = type;
            try {
                // 初始化消息工程
                Class c =  Class.forName(msg);
                m.msgFactory = (IMessageFactory) c.newInstance();
                
                // 初始化receiver工厂
                c =  Class.forName(receiver);
                m.receFactory = (IReceiverFactory) c.newInstance();
                
                // 初始化sender工厂
                c =  Class.forName(sender);
                m.sendFactory = (ISenderManager) c.newInstance();
                
                this.connectorMap.put(m.type, m);
            } catch (Exception e) {
                // TODO Auto-generated catch block
                logger.error("load router type for " + m.type, e);
            }

        }

    }

    class RouterType{
        String type;
        IMessageFactory msgFactory;
        IReceiverFactory receFactory;
        ISenderManager sendFactory;
    }
    
    public static void main(String[] args) {
        RouterTypeManager.getInstance();
    }
}
